#include "matrixparser.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int initializeData(struct DATA *data, FILE *fp)
{
    data->eps = 0;
    data->max_it = 0;
    data->m_order = 0;
    data->row_test = 0;
    data->initialized = 0;
    data->a = NULL;
    data->b = NULL;
    data->x = NULL;
    data->str = NULL;

    if( (data->str=readText(fp)) != NULL )
    {
        if(readHeader(data->str,&data->m_order,&data->row_test,&data->eps,&data->max_it))
        {
            data->a = (double*)malloc(sizeof(double)*data->m_order*data->m_order);
            data->b = (double*)malloc(sizeof(double)*data->m_order);
            data->x = (double*)malloc(data->m_order * sizeof(double));

            if(readMatrix(data->str,data->x,data->a,data->b,data->m_order))
            {
                data->initialized = 1;
                return 1;
            }
            free(data->a);
            free(data->b);
            free(data->x);
            data->a = NULL;
            data->b = NULL;
            data->x = NULL;
        }
    }

    printf("initializeData: Could not initialize the data struct\n");
    return 0;
}

int readHeader(char *str, int *m_order,int *row_test,double *eps, int *max_it)
{
    if(str)
    {
        char delim[] = " \n";

        sscanf(strtok(str, delim),"%d",m_order);
        sscanf(strtok(NULL, delim),"%d",row_test);
        *eps = strtod(strtok(NULL, delim),NULL);
        sscanf(strtok(NULL, delim),"%d",max_it);

        return 1;
    }

    printf("readHeader: string array not initialized yet \n");
    return 0;
}

int readMatrix(char *str, double *x, double *a, double *b,int m_order)
{
    if( (str!=NULL) && (a!=NULL) && (b!=NULL) && (x!=NULL))
    {
        int i = 0;
        int range = 1;
        char delim[] = " \n";

        for(i = 0; i < m_order*m_order; i++)
            a[i] = strtod(strtok(NULL,delim),NULL);

        for(i = 0; i <m_order; i++)
        {
            b[i] = strtod(strtok(NULL,delim),NULL);

            /*Generate random values for x*/
            x[i] = (random()/(double)RAND_MAX)*range;
        }
        return 1;
    }

    printf("readMatrix: array(s) not initialized yet\n");
    return 0;
}

char *readText(FILE *fp)
{
    if(fp!=NULL)
    {
        int bytes_numb = 0;
        char *temp;

        rewind(fp);
        fseek(fp,0,SEEK_END);
        bytes_numb = ftell(fp);

        temp = (char*)malloc(bytes_numb*sizeof(char)+1);

        rewind(fp);
        fread(temp,sizeof(char),bytes_numb,fp);
        temp[bytes_numb+1] = '\0';

        return temp;
    }

    printf("readText: file not created\n");
    return NULL;
}

void printHeader(struct DATA *data)
{

    printf("J_ORDER = %d\n",data->m_order);
    printf("J_ROW_TEST = %d\n",data->row_test);
    printf("J_ERROR = %lf\n",data->eps);
    printf("J_ITE_MAX = %d\n",data->max_it);
}

int printDataStruct(struct DATA *data)
{
    if(data->a && data->b && data->x && data->initialized)
    {
        int i = 0;
        int stop = data->m_order*data->m_order;

        printf("\nmatrix: ");
        for(i=0;i<stop;i++)
            printf("%c ",data->str[i] );
        printf("\n");

        printf("a: ");
        for(i=0;i<stop;i++)
            printf("%lf ",data->a[i]);
        printf("\n");

        printf("b: ");
        for(i=0;i<data->m_order;i++)
            printf("%lf ",data->b[i]);
        printf("\n");

        printf("x: ");
        for(i=0;i<data->m_order;i++)
            printf("%lf ",data->x[i]);
        printf("\n");

        return 1;

    }
    printf("printDataStruct: Could not initialize the data struct\n");
    return 0;
}

int removeDataStruct(struct DATA *data)
{
    if(data->initialized)
    {
        free(data->a);
        free(data->b);
        free(data->str);
        free(data->x);

        data->eps = 0;
        data->max_it = 0;
        data->m_order = 0;
        data->row_test = 0;
        data->initialized = 0;

        return 1;
    }

    printf("removeDataStruct: the data struct wasn't created yet\n");
    return 0;
}
